<?php
declare(strict_types=1);

namespace app\service;

use app\model\{MerchantApplication, PlatformConfig};
use Alipay\EasySDK\Kernel\Factory;
use Alipay\EasySDK\Kernel\Config;
use think\facade\Log;

class AlipayService extends BaseService
{
    protected $config;
    protected $merchant_id;
    protected $instance;
    
    public function __construct($merchant_id)
    {
        $this->merchant_id = $merchant_id;
        $this->initConfig();
    }
    
    /**
     * 初始化配置
     */
    protected function initConfig()
    {
        // 获取商家支付宝配置
        $appConfig = MerchantApplication::where([
            'merchant_id' => $this->merchant_id,
            'application_type' => 3 // 支付宝小程序
        ])->find();
        
        // 获取平台支付宝配置
        $platformConfig = PlatformConfig::where('group_name', 'alipay')
            ->column('config_value', 'config_key');
        
        $options = new Config();
        $options->protocol = 'https';
        $options->gatewayHost = 'openapi.alipay.com';
        $options->signType = 'RSA2';
        
        $options->appId = $appConfig->app_id ?? '';
        
        // 应用私钥
        $options->merchantPrivateKey = $platformConfig['merchant_private_key'] ?? '';
        
        // 支付宝公钥
        $options->alipayPublicKey = $platformConfig['alipay_public_key'] ?? '';
        
        // 设置异步通知接收服务地址
        $options->notifyUrl = $platformConfig['notify_url'] ?? '';
        
        // 设置AES密钥
        $options->encryptKey = $platformConfig['encrypt_key'] ?? '';
        
        Factory::setOptions($options);
    }
    
    /**
     * 获取支付宝实例
     */
    protected function getInstance()
    {
        if (!$this->instance) {
            $this->instance = Factory::getClient();
        }
        return $this->instance;
    }
    
    /**
     * 发送模板消息
     */
    public function sendTemplateMessage($params)
    {
        try {
            $result = $this->getInstance()
                ->marketing()
                ->templateMessage()
                ->send($params['to_user_id'], $params['template_id'], $params['data']);
            
            if ($result->code === '10000') {
                return true;
            }
            
            Log::error('发送支付宝模板消息失败', [
                'params' => $params,
                'result' => $result->toMap()
            ]);
            return false;
        } catch (\Exception $e) {
            Log::error('发送支付宝模板消息异常: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * 转账到支付宝账户
     */
    public function transfer($params)
    {
        try {
            $result = $this->getInstance()
                ->util()
                ->generic()
                ->execute('alipay.fund.trans.uni.transfer', [], [
                    'out_biz_no' => $params['out_trade_no'],
                    'trans_amount' => $params['amount'],
                    'product_code' => 'TRANS_ACCOUNT_NO_PWD',
                    'biz_scene' => 'DIRECT_TRANSFER',
                    'payee_info' => [
                        'identity' => $params['account'],
                        'identity_type' => 'ALIPAY_LOGON_ID',
                        'name' => $params['real_name']
                    ]
                ]);
            
            if ($result->code === '10000') {
                return true;
            }
            
            Log::error('支付宝转账失败', [
                'params' => $params,
                'result' => $result->toMap()
            ]);
            return false;
        } catch (\Exception $e) {
            Log::error('支付宝转账异常: ' . $e->getMessage());
            return false;
        }
    }
    
    /**
     * 退款
     */
    public function refund($params)
    {
        try {
            $result = $this->getInstance()
                ->payment()
                ->common()
                ->refund($params['out_trade_no'], $params['refund_amount'], $params['refund_desc']);
            
            if ($result->code === '10000') {
                return true;
            }
            
            Log::error('支付宝退款失败', [
                'params' => $params,
                'result' => $result->toMap()
            ]);
            return false;
        } catch (\Exception $e) {
            Log::error('支付宝退款异常: ' . $e->getMessage());
            return false;
        }
    }
} 